package cn.anosi.exception;

import com.alibaba.druid.support.json.JSONUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class CustomExceptionResolver implements HandlerExceptionResolver {

	protected Logger logger = LoggerFactory.getLogger(this.getClass().getName());

	// 前端控制器DispatcherServlet在进行HandlerMapping、调用HandlerAdapter执行Handler过程中，如果遇到异常就会执行此方法
	// handler最终要执行的Handler，它的真实身份是HandlerMethod
	// Exception ex就是接收到异常信息
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
	                                     Exception ex) {
		// 输出异常
		//ex.printStackTrace();
		logger.error(ex.getMessage(), ex);

		// 统一异常处理代码
		// 针对系统自定义的CustomException异常，就可以直接从异常类中获取异常信息，将异常处理在错误页面展示
		// 异常信息
		String message = null;
		CustomException customException = null;
		// 如果ex是系统 自定义的异常，直接取出异常信息
		if (ex instanceof CustomException) {
			customException = (CustomException) ex;
		} /*else if (ex instanceof UnauthorizedException) {
			customException = new CustomException("没有权限");
		}*/else if(ex instanceof DuplicateKeyException){
			customException = new CustomException("数据已存在");
		} else {
			// 针对非CustomException异常，对这类重新构造成一个CustomException，异常信息为“未知错误”
			customException = new CustomException("未知错误");
		}

		// 错误 信息
		message = customException.getMessage();
		request.setAttribute("message", message);

		// JSP格式返回
		if (!(request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With") != null
				&& request.getHeader("X-Requested-With").contains("XMLHttpRequest")))) {
			// 如果不是异步请求
			// 转向到错误 页面
			try {
				request.getRequestDispatcher("/error").forward(request, response);
			} catch (ServletException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		} else {
			// 如果是ajax请求，JSON格式返回
			try {
				response.setContentType("application/json;charset=UTF-8");
				PrintWriter writer = response.getWriter();
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("error", true);
				map.put("msg", message);
				writer.write(JSONUtils.toJSONString(map));
				writer.flush();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return null;
		}
	}

}
